package link.luyu.plugin.brochain.web3.methods.response;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigInteger;
import java.util.List;
import org.web3j.utils.Numeric;

public class Block {

    private String number;

    @JsonProperty("blockHash")
    private String hash;

    private String parentHash;
    private String transactionsRoot;
    private String stateRoot;
    private String receiptsRoot;
    private String pagesRoot;
    private String timestamp;
    private String extraData;

    @JsonProperty("regionList")
    private List<RegionPage> regionPages;

    public Block() {}

    public Block(
            String number,
            String hash,
            String parentHash,
            String transactionsRoot,
            String stateRoot,
            String receiptsRoot,
            String pagesRoot,
            String timestamp,
            String extraData,
            List<RegionPage> regionPages) {
        this.number = number;
        this.hash = hash;
        this.parentHash = parentHash;
        this.transactionsRoot = transactionsRoot;
        this.stateRoot = stateRoot;
        this.receiptsRoot = receiptsRoot;
        this.pagesRoot = pagesRoot;
        this.timestamp = timestamp;
        this.extraData = extraData;
        this.regionPages = regionPages;
    }

    public BigInteger getNumber() {
        return Numeric.decodeQuantity(number);
    }

    public String getNumberRaw() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getHash() {
        return hash;
    }

    public void setHash(String hash) {
        this.hash = hash;
    }

    public String getParentHash() {
        return parentHash;
    }

    public void setParentHash(String parentHash) {
        this.parentHash = parentHash;
    }

    public String getTransactionsRoot() {
        return transactionsRoot;
    }

    public void setTransactionsRoot(String transactionsRoot) {
        this.transactionsRoot = transactionsRoot;
    }

    public String getStateRoot() {
        return stateRoot;
    }

    public void setStateRoot(String stateRoot) {
        this.stateRoot = stateRoot;
    }

    public String getReceiptsRoot() {
        return receiptsRoot;
    }

    public void setReceiptsRoot(String receiptsRoot) {
        this.receiptsRoot = receiptsRoot;
    }

    public String getPagesRoot() {
        return pagesRoot;
    }

    public void setPagesRoot(String pagesRoot) {
        this.pagesRoot = pagesRoot;
    }

    public BigInteger getTimestamp() {
        return Numeric.decodeQuantity(timestamp);
    }

    public String getTimestampRaw() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    public String getExtraData() {
        return extraData;
    }

    public void setExtraData(String extraData) {
        this.extraData = extraData;
    }

    public List<RegionPage> getRegionPages() {
        return regionPages;
    }

    public void setRegionPages(List<RegionPage> regionPages) {
        this.regionPages = regionPages;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Block)) {
            return false;
        }

        Block block = (Block) o;

        if (getNumberRaw() != null
                ? !getNumberRaw().equals(block.getNumberRaw())
                : block.getNumberRaw() != null) {
            return false;
        }
        if (getHash() != null ? !getHash().equals(block.getHash()) : block.getHash() != null) {
            return false;
        }
        if (getParentHash() != null
                ? !getParentHash().equals(block.getParentHash())
                : block.getParentHash() != null) {
            return false;
        }
        if (getTransactionsRoot() != null
                ? !getTransactionsRoot().equals(block.getTransactionsRoot())
                : block.getTransactionsRoot() != null) {
            return false;
        }
        if (getStateRoot() != null
                ? !getStateRoot().equals(block.getStateRoot())
                : block.getStateRoot() != null) {
            return false;
        }
        if (getReceiptsRoot() != null
                ? !getReceiptsRoot().equals(block.getReceiptsRoot())
                : block.getReceiptsRoot() != null) {
            return false;
        }
        if (getPagesRoot() != null
                ? !getPagesRoot().equals(block.getPagesRoot())
                : block.getPagesRoot() != null) {
            return false;
        }
        if (getTimestampRaw() != null
                ? !getTimestampRaw().equals(block.getTimestampRaw())
                : block.getTimestampRaw() != null) {
            return false;
        }
        if (getExtraData() != null
                ? !getExtraData().equals(block.getExtraData())
                : block.getExtraData() != null) {
            return false;
        }
        return getRegionPages() != null
                ? getRegionPages().equals(block.getRegionPages())
                : block.getRegionPages() == null;
    }

    @Override
    public int hashCode() {
        int result = getNumberRaw() != null ? getNumberRaw().hashCode() : 0;
        result = 31 * result + (getHash() != null ? getHash().hashCode() : 0);
        result = 31 * result + (getParentHash() != null ? getParentHash().hashCode() : 0);
        result =
                31 * result
                        + (getTransactionsRoot() != null ? getTransactionsRoot().hashCode() : 0);
        result = 31 * result + (getStateRoot() != null ? getStateRoot().hashCode() : 0);
        result = 31 * result + (getReceiptsRoot() != null ? getReceiptsRoot().hashCode() : 0);
        result = 31 * result + (getPagesRoot() != null ? getPagesRoot().hashCode() : 0);
        result = 31 * result + (getExtraData() != null ? getExtraData().hashCode() : 0);
        result = 31 * result + (getTimestampRaw() != null ? getTimestampRaw().hashCode() : 0);
        result = 31 * result + (getRegionPages() != null ? getRegionPages().hashCode() : 0);
        return result;
    }

    public static class RegionPage {

        @JsonProperty("regionid")
        private String regionId;

        @JsonProperty("regionPageHash")
        private String pageHash;

        public RegionPage() {}

        public RegionPage(String regionId, String pageHash) {
            this.regionId = regionId;
            this.pageHash = pageHash;
        }

        public String getRegionId() {
            return regionId;
        }

        public void setRegionId(String regionId) {
            this.regionId = regionId;
        }

        public String getPageHash() {
            return pageHash;
        }

        public void setPageHash(String pageHash) {
            this.pageHash = pageHash;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof RegionPage)) {
                return false;
            }

            RegionPage block = (RegionPage) o;

            if (getRegionId() != null
                    ? !getRegionId().equals(block.getRegionId())
                    : block.getRegionId() != null) {
                return false;
            }
            return getPageHash() != null
                    ? getPageHash().equals(block.getPageHash())
                    : block.getPageHash() == null;
        }

        @Override
        public int hashCode() {
            int result = getRegionId() != null ? getRegionId().hashCode() : 0;
            result = 31 * result + (getPageHash() != null ? getPageHash().hashCode() : 0);
            return result;
        }
    }
}
